package com.core.cloudbusiness.system.demo.controller;

import com.core.cloudcommon.CommonResult;
import com.core.cloudcommon.trace.TraceContext;
import com.core.cloudcommon.trace.TraceLogger;
import com.core.cloudcommon.trace.Traceable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author =====Lqj=====
 * @className TraceExampleController
 * @description 链路追踪使用示例控制器
 * @create 2024/12/17 10:30
 **/
@Slf4j
@RestController
@RequestMapping("/api/demo/trace")
public class TraceExampleController {

    /**
     * 基本链路追踪示例
     */
    @GetMapping("/basic")
    @Traceable(operation = "基本示例", description = "演示基本的链路追踪功能")
    public CommonResult<Map<String, Object>> basicExample() {
        // 记录业务开始
        TraceLogger.businessStart("基本示例", "开始执行基本示例", null);

        Map<String, Object> result = new HashMap<>();
        result.put("message", "这是一个基本的链路追踪示例");
        result.put("traceId", TraceContext.getTraceId());
        result.put("currentTime", System.currentTimeMillis());

        // 模拟一些业务操作
        simulateBusinessOperation();
        simulateDatabaseOperation();
        simulateCacheOperation();

        // 记录业务结束
        TraceLogger.businessEnd("基本示例", "基本示例执行完成", result, TraceContext.getElapsedTime());

        return CommonResult.OK(result);
    }

    /**
     * 复杂业务流程示例
     */
    @PostMapping("/complex")
    @Traceable(operation = "复杂业务流程", description = "演示复杂业务流程的链路追踪", slowThreshold = 500)
    public CommonResult<Map<String, Object>> complexExample(@RequestBody Map<String, Object> params) {
        TraceLogger.businessStart("复杂业务流程", "开始执行复杂业务流程", params);

        Map<String, Object> result = new HashMap<>();
        
        try {
            // 步骤1：参数验证
            TraceLogger.business("参数验证", "验证输入参数", params);
            validateParams(params);

            // 步骤2：数据查询
            TraceLogger.business("数据查询", "查询相关数据", null);
            Map<String, Object> data = queryData(params);

            // 步骤3：业务处理
            TraceLogger.business("业务处理", "执行核心业务逻辑", data);
            Map<String, Object> processedData = processData(data);

            // 步骤4：数据保存
            TraceLogger.business("数据保存", "保存处理结果", processedData);
            saveData(processedData);

            // 步骤5：缓存更新
            TraceLogger.business("缓存更新", "更新相关缓存", null);
            updateCache(processedData);

            result.put("success", true);
            result.put("data", processedData);
            result.put("traceId", TraceContext.getTraceId());

        } catch (Exception e) {
            TraceLogger.error("复杂业务流程执行失败: {}", e.getMessage(), e);
            result.put("success", false);
            result.put("error", e.getMessage());
            result.put("traceId", TraceContext.getTraceId());
        }

        TraceLogger.businessEnd("复杂业务流程", "复杂业务流程执行完成", result, TraceContext.getElapsedTime());
        return CommonResult.OK(result);
    }

    /**
     * 外部接口调用示例
     */
    @GetMapping("/external")
    @Traceable(operation = "外部接口调用", description = "演示外部接口调用的链路追踪")
    public CommonResult<Map<String, Object>> externalCallExample() {
        TraceLogger.businessStart("外部接口调用", "开始调用外部接口", null);

        Map<String, Object> result = new HashMap<>();
        
        // 模拟调用外部接口
        long startTime = System.currentTimeMillis();
        Map<String, Object> externalResult = callExternalService();
        long elapsedTime = System.currentTimeMillis() - startTime;

        TraceLogger.externalCall("外部服务", "getUserInfo", null, externalResult, elapsedTime);

        result.put("externalResult", externalResult);
        result.put("traceId", TraceContext.getTraceId());

        TraceLogger.businessEnd("外部接口调用", "外部接口调用完成", result, TraceContext.getElapsedTime());
        return CommonResult.OK(result);
    }

    /**
     * 性能监控示例
     */
    @GetMapping("/performance")
    @Traceable(operation = "性能监控", description = "演示性能监控的链路追踪", slowThreshold = 100)
    public CommonResult<Map<String, Object>> performanceExample() {
        TraceLogger.businessStart("性能监控", "开始性能监控示例", null);

        Map<String, Object> result = new HashMap<>();

        // 快速操作
        long startTime = System.currentTimeMillis();
        fastOperation();
        long fastTime = System.currentTimeMillis() - startTime;
        TraceLogger.performance("快速操作", fastTime, null);

        // 慢操作
        startTime = System.currentTimeMillis();
        slowOperation();
        long slowTime = System.currentTimeMillis() - startTime;
        TraceLogger.performance("慢操作", slowTime, null);

        result.put("fastOperationTime", fastTime);
        result.put("slowOperationTime", slowTime);
        result.put("traceId", TraceContext.getTraceId());

        TraceLogger.businessEnd("性能监控", "性能监控示例完成", result, TraceContext.getElapsedTime());
        return CommonResult.OK(result);
    }

    /**
     * 安全事件示例
     */
    @PostMapping("/security")
    @Traceable(operation = "安全事件", description = "演示安全事件的链路追踪")
    public CommonResult<Map<String, Object>> securityExample(@RequestParam String action) {
        TraceLogger.businessStart("安全事件", "开始安全事件示例", action);

        Map<String, Object> result = new HashMap<>();

        // 模拟不同的安全事件
        switch (action) {
            case "login":
                TraceLogger.security("用户登录", "用户尝试登录系统", "INFO");
                result.put("event", "登录事件");
                break;
            case "unauthorized":
                TraceLogger.security("未授权访问", "用户尝试访问未授权资源", "WARN");
                result.put("event", "未授权访问事件");
                break;
            case "attack":
                TraceLogger.security("安全攻击", "检测到可疑的攻击行为", "ERROR");
                result.put("event", "安全攻击事件");
                break;
            default:
                result.put("event", "未知事件");
                break;
        }

        result.put("traceId", TraceContext.getTraceId());

        TraceLogger.businessEnd("安全事件", "安全事件示例完成", result, TraceContext.getElapsedTime());
        return CommonResult.OK(result);
    }

    /**
     * 获取当前链路信息
     */
    @GetMapping("/current")
    public CommonResult<Map<String, Object>> getCurrentTraceInfo() {
        TraceContext.TraceInfo traceInfo = TraceContext.getCurrentTraceInfo();
        
        Map<String, Object> result = new HashMap<>();
        if (traceInfo != null) {
            result.put("traceId", traceInfo.getTraceId());
            result.put("userId", traceInfo.getUserId());
            result.put("userName", traceInfo.getUserName());
            result.put("requestUri", traceInfo.getRequestUri());
            result.put("clientIp", traceInfo.getClientIp());
            result.put("startTime", traceInfo.getStartTime());
            result.put("elapsedTime", traceInfo.getElapsedTime());
        } else {
            result.put("message", "当前没有链路追踪上下文");
        }

        return CommonResult.OK(result);
    }

    // ========================================
    // 模拟方法
    // ========================================

    private void simulateBusinessOperation() {
        TraceLogger.business("模拟业务操作", "执行模拟的业务操作", null);
        try {
            Thread.sleep(50); // 模拟耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private void simulateDatabaseOperation() {
        TraceLogger.database("SELECT", "sys_user", "id = 1", "查询成功");
        try {
            Thread.sleep(30); // 模拟数据库查询耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private void simulateCacheOperation() {
        TraceLogger.cache("GET", "user:1", null, "缓存命中");
        try {
            Thread.sleep(10); // 模拟缓存操作耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private void validateParams(Map<String, Object> params) {
        if (params == null || params.isEmpty()) {
            throw new IllegalArgumentException("参数不能为空");
        }
    }

    private Map<String, Object> queryData(Map<String, Object> params) {
        TraceLogger.database("SELECT", "business_table", "condition", "查询成功");
        Map<String, Object> data = new HashMap<>();
        data.put("id", 1);
        data.put("name", "测试数据");
        return data;
    }

    private Map<String, Object> processData(Map<String, Object> data) {
        // 模拟数据处理
        data.put("processed", true);
        data.put("processTime", System.currentTimeMillis());
        return data;
    }

    private void saveData(Map<String, Object> data) {
        TraceLogger.database("INSERT", "result_table", "data", "保存成功");
        try {
            Thread.sleep(100); // 模拟保存耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private void updateCache(Map<String, Object> data) {
        TraceLogger.cache("SET", "result:1", data, "缓存更新成功");
        try {
            Thread.sleep(20); // 模拟缓存更新耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private Map<String, Object> callExternalService() {
        try {
            Thread.sleep(200); // 模拟外部接口调用耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("status", "success");
        result.put("data", "外部接口返回的数据");
        return result;
    }

    private void fastOperation() {
        try {
            Thread.sleep(50); // 快速操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private void slowOperation() {
        try {
            Thread.sleep(1500); // 慢操作，超过阈值
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
